#include "SimpleMesh.hpp"
#include "../../Graphics/Graphics.hpp"

namespace zzz{
SimpleMesh::SimpleMesh()
{}

void SimpleMesh::Clear()
{
  faces_.clear();
  vertices_.clear();
  triangles_.clear();
  normals_.clear();
  texcoords_.clear();
  ClrAllFlags();
}

void SimpleMesh::DrawTriangles()
{
  if (HasNoFlag(SMESH_TRI))
    return;
  glBegin(GL_TRIANGLES);
  for (zuint i=0; i<triangles_.size(); i++)
  {
    const Triangle &t = triangles_[i];
    glVertex3fv(t[0].Data());
    glVertex3fv(t[1].Data());
    glVertex3fv(t[2].Data());
  }
  glEnd();
}

void SimpleMesh::DrawTriangle(zuint i)
{
  if (HasNoFlag(SMESH_TRI))
    return;
  glBegin(GL_TRIANGLES);
    glVertex3fv(triangles_[i][0].Data());
    glVertex3fv(triangles_[i][1].Data());
    glVertex3fv(triangles_[i][2].Data());
  glEnd();
}

void SimpleMesh::DrawFaces()
{
  if (HasNoFlag(SMESH_POS))
    return;
  glBegin(GL_TRIANGLES);
  for (zuint i=0; i<faces_.size(); i++)
  {
    const Vector3i &f = faces_[i];
    glVertex3fv(vertices_[f[0]].Data());
    glVertex3fv(vertices_[f[1]].Data());
    glVertex3fv(vertices_[f[2]].Data());
  }
  glEnd();
}

void SimpleMesh::DrawFace(zuint i)
{
  if (HasNoFlag(SMESH_POS))
    return;
  glBegin(GL_TRIANGLES);
    glVertex3fv(vertices_[faces_[i][0]].Data());
    glVertex3fv(vertices_[faces_[i][1]].Data());
    glVertex3fv(vertices_[faces_[i][2]].Data());
  glEnd();
}

void SimpleMesh::DrawPoint(zuint i)
{
  if (HasNoFlag(SMESH_POS))
    return;
  glBegin(GL_POINTS);
    glVertex3fv(vertices_[i].Data());
  glEnd();
}

void SimpleMesh::FromTriangles()
{
  vertices_.clear();
  faces_.clear();
  map<Vector3f, zuint> m;
  map<Vector3f, zuint>::iterator mi;
  for (zuint n = 0; n<triangles_.size(); n++)
  {
    const Triangle &t = triangles_[n];
    Vector3i f;
    for (zuint i=0; i<3; i++)
    {
      mi=m.find(t[i]);
      if (mi==m.end())
      {
        f[i]=vertices_.size();
        vertices_.push_back(t[i]);
        m[t[i]]=f[i];
      }
      else
        f[i]=mi->second;
    }
    faces_.push_back(f);
  }
  SetFlag(SMESH_POS);
}

void SimpleMesh::ToTriangles()
{
  triangles_.clear();
  for (zuint i=0; i<faces_.size(); i++) {
    const Vector3i &f = faces_[i];
    triangles_.push_back(Triangle(vertices_[f[0]],vertices_[f[1]],vertices_[f[2]]));
  }
  SetFlag(SMESH_TRI);
}

void SimpleMesh::SetDataFlags()
{
  if (!vertices_.empty()) SetFlag(SMESH_POS);
  if (!normals_.empty()) SetFlag(SMESH_NOR);
  if (!texcoords_.empty()) SetFlag(SMESH_TEX);
  if (!triangles_.empty()) SetFlag(SMESH_TRI);
}

}